﻿// ------------------------------------------------------------------------------
// <copyright file="DropBard.cs" company="MyCompany.com">
//  Copyright © MyCompany.com. All rights reserved.
// </copyright>
// <author>Me</author>
// ------------------------------------------------------------------------------

namespace BTerrariaMod.Bards
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.Contracts;
    using System.Linq;
    using BTerrariaMod.Sugar;
    using Terraria;

    /// <summary>
    /// Announces items of interest that are dropped.
    /// </summary>
    public class DropBard
    {
        /// <summary>
        /// The action used to output.
        /// </summary>
        private readonly Action<string> output;

        /// <summary>
        /// A cache of dropped items.
        /// </summary>
        private IDictionary<string, DateTime> dropCache = new Dictionary<string, DateTime>();

        /// <summary>
        /// Initializes a new instance of the <see cref="DropBard"/> class.
        /// </summary>
        /// <param name="output">The output.</param>
        public DropBard(Action<string> output)
        {
            Contract.Assert(output != null);
            Contract.Ensures(this.output != null);
            this.output = output;
        }

        /// <summary>
        /// Announces the drops.
        /// </summary>
        /// <param name="items">The items.</param>
        public void AnnounceDrops(IEnumerable<Item> items)
        {
            if (items == null)
            {
                return;
            }

            foreach (var i in items.Where(this.IsItemOfInterest))
            {
                if (!this.dropCache.ContainsKey(i.name) || (DateTime.Now - this.dropCache[i.name]).TotalSeconds > 30)
                {
                    if (!this.dropCache.ContainsKey(i.name))
                    {
                        this.dropCache.Add(i.name, DateTime.Now);
                    }
                    else
                    {
                        this.dropCache[i.name] = DateTime.Now;
                    }

                    string text = string.Empty;
                    if (i.stack < 2 || i.maxStack < 2)
                    {
                        text += "A ";
                    }
                    else
                    {
                        text += i.stack + " ";
                    }

                    text += i.name + " has entered the world";
                    this.output(text);
                }
            }
        }

        /// <summary>
        /// Determines whether the item is of interest.
        /// </summary>
        /// <param name="i">The item.</param>
        /// <returns>
        ///   <c>true</c> if [is item of interest] [the specified i]; otherwise, <c>false</c>.
        /// </returns>
        private bool IsItemOfInterest(Item i)
        {
            if (i == null || i.name.IsNullOrEmpty())
            {
                return false;
            }

            var endswiths = new[] { "statue", "fright", "might", "sight" };
            foreach (var ending in endswiths)
            {
                if (i.name.EndsWith(ending, StringComparison.CurrentCultureIgnoreCase))
                {
                    return true;
                }
            }

            return false;
        }
    }
}
